﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Xcj.Mes.Core.FileHelper
{
    public class MyFileHelper : IDisposable
    {
        public static MyFileHelper myFileHelper;
        public CancellationTokenSource cts = new CancellationTokenSource();

        static MyFileHelper()
        {
            myFileHelper = new MyFileHelper();
        }

        public void Dispose()
        {
            try { cts.Cancel(); } catch { }
        }

        public MyFileHelper()
        {
            Task.Run(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                Thread.CurrentThread.Priority = ThreadPriority.Lowest;

                while (true)
                {
                    if (cts?.Token.IsCancellationRequested ?? false)
                        break;

                    Dictionary<string, FileText> _dictFileText = new Dictionary<string, FileText>();
                    lock (lockDictFileText)
                    {
                        _dictFileText = dictFileText;
                        dictFileText = new Dictionary<string, FileText>();
                    }

                    foreach (var item in _dictFileText)
                    {
                        if (!string.IsNullOrEmpty(item.Key))
                        {
                            try
                            {
                                using (FileStream fs = new FileStream(item.Key, FileMode.Append, FileAccess.Write, FileShare.Write, 8192))
                                {
                                    using (StreamWriter sw = new StreamWriter(fs, item.Value.encoding, 8192))
                                    {
                                        try
                                        {
                                            fs.Seek(0, SeekOrigin.End);
                                            List<string> listText = item.Value.listText;
                                            foreach (string s in listText)
                                                sw.Write(s);
                                            sw.AutoFlush = true;
                                        }
                                        catch { }
                                        sw.Close();
                                    }
                                    fs.Close();
                                }
                            }
                            catch { }
                        }
                    }

                    Thread.Sleep(2000);
                }
            });
        }

        private object lockDictFileText = new object();
        private Dictionary<string, FileText> dictFileText = new Dictionary<string, FileText>();

        public void Append(string file, string text, Encoding encoding)
        {
            if (string.IsNullOrEmpty(file?.Trim()) || string.IsNullOrEmpty(text?.Trim()))
                return;

            lock (lockDictFileText)
            {
                try
                {
                    string path = System.IO.Path.GetDirectoryName(file)?.Trim();
                    if (string.IsNullOrEmpty(path)) return;
                    if (!Directory.Exists(path))
                        try { Directory.CreateDirectory(path); } catch { return; }

                    if (!File.Exists(file))
                        if (!CreateFile(file, true, encoding)) return;

                    if (dictFileText.ContainsKey(file))
                        dictFileText[file].listText.Add(text);
                    else
                    {
                        FileText fileText = new FileText();
                        fileText.encoding = encoding;
                        fileText.listText.Add(text);
                        dictFileText.Add(file, fileText);
                    }
                }
                catch { }
            }
        }

        public bool CreateFile(string file, bool append, Encoding encoding)
        {
            try
            {
                using (StreamWriter sw = new StreamWriter(file, append, encoding))
                    sw.Close();
                
                return true;
            }
            catch {}
            
            return false;
        }
    }

    public class FileText
    {
        public Encoding encoding { get; set; } = Encoding.GetEncoding("gb2312");

        public List<string> listText { get; set; } = new List<string>();
    }
}
